

//an430 驱动显示模块

module lcd_drive(
		input						clk_50M,
		input						clk_9M,		//9M时钟
		input						rst,			//复位信号
		
		//an430
		output					lcdclk_9M,				//an430时钟
		output					lcd_de,					//an430使能信号
		output					lcd_vsync,				//场同步信号(垂直)
		output					lcd_hsync,				//行同步信号(水平)
		output reg[23:0]		lcd_data,				//an430显示数据 rgb565 
		
		output					data_req,
		input[15:0]				data_in,
		input[15:0]				mode
	
	
);

localparam  H_TOTAL_TIME		= 525;
localparam	H_ADDR_TIME			= 480;
localparam	H_SYNC_TIME			= 41;
localparam	H_BACK_PORCH		= 2;

localparam 	V_TOTAL_TIME		= 286;
localparam	V_ADDR_TIME			= 272;
localparam	V_SYNC_TIME			= 10;
localparam	V_BACK_PORCH		= 2;





reg[11:0]		cnt_h;
reg[9:0]			cnt_v;

wire  	h_valid;		//水平有效
wire		v_valid;		//垂直有效


   
assign h_valid = (cnt_h >= H_SYNC_TIME +H_BACK_PORCH) && (cnt_h < H_TOTAL_TIME- H_BACK_PORCH);
assign v_valid = (cnt_v >= V_SYNC_TIME + V_BACK_PORCH) && (cnt_v < V_TOTAL_TIME - V_BACK_PORCH);


assign lcd_de = v_valid & h_valid;   //同时有效的时候，置1
assign data_req = ((cnt_v >= V_SYNC_TIME + V_BACK_PORCH) && (cnt_v < V_TOTAL_TIME - V_BACK_PORCH)) & ((cnt_h >= H_SYNC_TIME +H_BACK_PORCH-'d6) && (cnt_h < H_TOTAL_TIME- H_BACK_PORCH-'d6));
assign lcdclk_9M = ~clk_9M;			//lcd时钟
assign lcd_hsync = (cnt_h < H_SYNC_TIME) ? 1'b0 : 1'b1;
assign lcd_vsync = (cnt_v < V_SYNC_TIME) ? 1'b0 : 1'b1;

always@(posedge clk_9M or negedge rst)
begin
	if(rst == 1'b0)
		cnt_h <= 'd0;
	else if(cnt_h >= H_TOTAL_TIME)
		cnt_h <= 'd0;
	else
		cnt_h <= cnt_h + 1'b1;
end

always@(posedge clk_9M or negedge rst)
begin
	if(rst == 1'b0)
		cnt_v <= 'd0;
	else if(cnt_v >= V_TOTAL_TIME &&cnt_h >= H_TOTAL_TIME)
		cnt_v <= 'd0;
	else if(cnt_h >= H_TOTAL_TIME)
		cnt_v <= cnt_v + 1'b1;
end


wire[15:0]	dat;
always@(posedge clk_9M or negedge rst)
begin
	if(rst == 1'b0)
		lcd_data = 'd0;
		
	else if(v_valid && ((cnt_h >= H_SYNC_TIME +H_BACK_PORCH-1) && (cnt_h < H_TOTAL_TIME- H_BACK_PORCH-1)))
	begin
		if(mode[15:8] == "1" || mode == 'd0)
			lcd_data = {dat2[15:11],3'b0,dat2[10:5],2'b0,dat2[4:0],3'b0};
		else
			lcd_data = {dat2,dat2[7:0]};
		
	end
	else
		lcd_data = 24'hEABCbb;
end

reg[15:0]	dat1,dat2;

always@(posedge clk_9M or negedge rst)
begin
	if(rst == 1'b0)
	begin
		dat1 <= 'd0;
		dat2 <= 'd0;
	end
	else begin
		dat1 <= data_in;
		dat2 <= dat1;
	end
end

endmodule 